//
// Copyright (C) 2020 IOTech Ltd
//
// SPDX-License-Identifier: Apache-2.0

package http

import (
	"github.com/edgexfoundry/edgex-go/internal/app/core/metadata/application"
	requestDTO "github.com/edgexfoundry/edgex-go/internal/app/dtos/requests"
	responseDTO "github.com/edgexfoundry/edgex-go/internal/app/dtos/responses"
	metadataContainer "github.com/edgexfoundry/edgex-go/internal/core/metadata/container"
	"github.com/edgexfoundry/edgex-go/internal/io"
	"github.com/edgexfoundry/edgex-go/internal/pkg"
	"github.com/edgexfoundry/edgex-go/internal/pkg/correlation"
	"github.com/edgexfoundry/edgex-go/internal/pkg/utils"
	"github.com/edgexfoundry/go-mod-bootstrap/v2/bootstrap/container"
	"github.com/edgexfoundry/go-mod-bootstrap/v2/di"
	"github.com/edgexfoundry/go-mod-core-contracts/v2/common"
	commonDTO "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common"
	"log"
	"math"
	"net/http"
)

/**
 * @Description
 * @method
 * @Date 2023-2-20
 * @Param
 * @return
 **/

type ProductCategoryServiceController struct {
	reader io.DtoReader
	dic    *di.Container
}

/**
 * @Description  创建并初始化  NewProductCategoryServiceController
 * @method
 * @Date 2023-02-14
 * @Param
 * @return
 **/

// NewProductCategoryServiceController creates and initializes an NewProductCategoryServiceController
func NewProductCategoryServiceController(dic *di.Container) *ProductCategoryServiceController {
	return &ProductCategoryServiceController{
		reader: io.NewJsonDtoReader(),
		dic:    dic,
	}
}

/**
 * @Description  获取产品分组列表
 * @method  GetProductCategorysList
 * @Date 2023-2-14
 * @Param
 * @return
 **/

func (dc *ProductCategoryServiceController) GetProductCategorysList(w http.ResponseWriter, r *http.Request) {

	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()
	config := metadataContainer.ConfigurationFrom(dc.dic.Get)

	// parse URL query string for offset, limit, and labels
	offset, limit, labels, err := utils.ParseGetAllObjectsRequestQueryString(r, 0, math.MaxInt32, -1, config.Service.MaxResultCount)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	//devices, totalCount, err := application.AllDevices(offset, limit, labels, dc.dic)
	productCategorys, totalCount, err := application.AllProductCategorys(offset, limit, labels, dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := responseDTO.NewMultiProductCategorysResponse("", "", http.StatusOK, totalCount, productCategorys)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

/**
 * @Description 产品分组查询所有，不分分组
 * @method
 * @auth kely
 * @Date 2023-3-8
 * @Param
 * @return
 **/

func (pc *ProductCategoryServiceController) ProdcutCategoryOwn(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(pc.dic.Get)
	ctx := r.Context()

	productCategorys, totalCount, err := application.ProdcutCategoryOwn(pc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	response := responseDTO.NewMultiProductCategorysResponse("", "", http.StatusOK, totalCount, productCategorys)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

/**
 * @Description 产品分组模糊查询
 * @method
 * @auth kely
 * @Date 2023-2-23
 * @Param
 * @return
 **/

func (dc *ProductCategoryServiceController) ProdcutCategoryByName(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()
	config := metadataContainer.ConfigurationFrom(dc.dic.Get)

	// parse URL query string for offset, limit, and name
	offset, limit, labels, err := utils.ParseGetAllObjectsRequestQueryString(r, 0, math.MaxInt32, -1, config.Service.MaxResultCount)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	print(labels) //输出下
	//获取所有请求参数
	query := r.URL.Query()
	name, ok := query["name"]
	if !ok || len(name[0]) < 1 {
		log.Println("Url Param 'name' is missing")
		return
	}
	//devices, totalCount, err := application.AllDevices(offset, limit, labels, dc.dic)

	productCategorys, totalCount, err := application.ProductCategorysByName(offset, limit, name[0], dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := responseDTO.NewMultiProductCategorysResponse("", "", http.StatusOK, totalCount, productCategorys)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}

/**
 * @Description 产品分组新增
 * @method
 * @auth kely
 * @Date 2023-2-21
 * @Param
 * @return
 **/

func (dc *ProductCategoryServiceController) AddProductCategory(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}

	lc := container.LoggingClientFrom(dc.dic.Get)

	ctx := r.Context()
	correlationId := correlation.FromContext(ctx)
	// 获取数据并把数据转为对象
	var reqDTOs []requestDTO.AddProductCategoryRequest
	err := dc.reader.Read(r.Body, &reqDTOs)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}
	productCategorys := requestDTO.AddProductCategoryReqToDeviceModels(reqDTOs)

	var addResponses []interface{}
	for i, d := range productCategorys {
		var response interface{}
		reqId := reqDTOs[i].RequestId
		// 新增功能
		newId, err := application.AddProductCategory(d, ctx, dc.dic)
		if err != nil {
			lc.Error(err.Error(), common.CorrelationHeader, correlationId)
			lc.Debug(err.DebugMessages(), common.CorrelationHeader, correlationId)
			response = commonDTO.NewBaseResponse(
				reqId,
				err.Message(),
				err.Code())
		} else {
			response = commonDTO.NewBaseWithIdResponse(
				reqId,
				"",
				http.StatusCreated,
				newId)
		}
		addResponses = append(addResponses, response)
	}

	utils.WriteHttpHeader(w, ctx, http.StatusMultiStatus)
	pkg.EncodeAndWriteResponse(addResponses, w, lc)
}

/**
 * @Description 产品分类修改
 * @method
 * @auth kely
 * @Date 2023-2-28
 * @Param
 * @return
 **/

func (dc *ProductCategoryServiceController) UpdateProductCategory(w http.ResponseWriter, r *http.Request) {
	if r.Body != nil {
		defer func() { _ = r.Body.Close() }()
	}

	lc := container.LoggingClientFrom(dc.dic.Get)

	ctx := r.Context()
	correlationId := correlation.FromContext(ctx)

	var reqDTOs []requestDTO.UpdateproductCategoryRequest
	err := dc.reader.Read(r.Body, &reqDTOs)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	var updateResponses []interface{}
	for _, dto := range reqDTOs {
		var response interface{}
		reqId := dto.RequestId
		err := application.PatchProductCategory(dto.ProductCategory, ctx, dc.dic)
		if err != nil {
			lc.Error(err.Error(), common.CorrelationHeader, correlationId)
			lc.Debug(err.DebugMessages(), common.CorrelationHeader, correlationId)
			response = commonDTO.NewBaseResponse(
				reqId,
				err.Message(),
				err.Code())
		} else {
			response = commonDTO.NewBaseResponse(
				reqId,
				"",
				http.StatusOK)
		}
		updateResponses = append(updateResponses, response)
	}

	utils.WriteHttpHeader(w, ctx, http.StatusMultiStatus)
	pkg.EncodeAndWriteResponse(updateResponses, w, lc)
}

/**
 * @Description 根据产品分组id删除分组信息
 * @method
 * @auth kely
 * @Date 2023-3-1
 * @Param
 * @return
 **/

func (dc *ProductCategoryServiceController) DeleteProductCategoryById(w http.ResponseWriter, r *http.Request) {
	lc := container.LoggingClientFrom(dc.dic.Get)
	ctx := r.Context()

	//// URL parameters
	//vars := mux.Vars(r)
	//id := vars[common.Id]
	//获取所有请求参数idd
	query := r.URL.Query()
	id, ok := query["id"]
	if !ok || len(id[0]) < 1 {
		log.Println("Url Param 'name' is missing")
		return
	}

	err := application.DeleteProductCategoryById(id[0], ctx, dc.dic)
	if err != nil {
		utils.WriteErrorResponse(w, ctx, lc, err, "")
		return
	}

	response := commonDTO.NewBaseResponse("", "", http.StatusOK)
	utils.WriteHttpHeader(w, ctx, http.StatusOK)
	pkg.EncodeAndWriteResponse(response, w, lc)
}
